#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <limits.h>
#include <math.h>
#include <stdbool.h>

#define LIST 122

#if (LIST == 117)
// 1-17 一个十进制小数要能用浮点数精确地表示,最后一位必须是5(当然这是必要条件,并非充分条件) 
#include <stdio.h>
int main(void)
{
    float f1=34.6;
    float f2=34.5;
    float f3=34.0;
    printf("34.6-34.0=%f\n",f1-f3);
    printf("34.5-34.0=%f\n",f2-f3);
    return 0;
}

#elif(LIST == 118) 

// 1-18 浮点数计算示例
float average(float *arr,size_t size);

enum {array_size = 10};

int main(void)
{
    float arr[array_size];
    size_t i = 0;
    for (i = 0; i < array_size; i++)
    {
        arr[i] = 5.1;
    }

    // 浮点数保留到小数点22位
    printf("total / size = %.22f\n", average(arr,array_size));
    return 0;
}
float average(float *arr,size_t size)
{
    float total = 0.0;
    size_t i=0;
    if (size > 0 && size <= SIZE_MAX)
    {
        for (i = 0; i < size; i++)
        {
            total += arr[i];
            printf("arr[%d] = %.22f , total = %.22f\n", i, arr[i], total);
        }
        return total / size;
    }
    else
    {
            return 0.0;
    }
}

#elif (LIST == 119)
// 1-19 整数代替浮点数示例
#include <stdio.h>
#include <limits.h>
float average(int *arr,size_t size);
enum { array_size = 10 };
int main(void)
{
    int arr[array_size];
    size_t i=0;
    for (i = 0; i < array_size; i++)
    {
            arr[i] = 510;
    }
    printf("total / size = %f\n", average(arr,array_size));
    return 0;
}
float average(int *arr,size_t size)
{
    int total = 0;
    size_t i = 0;
    if (size > 0 && size <= SIZE_MAX)
    {
        for (i = 0; i < size; i++)
        {
        total += arr[i];
        printf("arr[%d] = %f , total = %f\n", i, (float)arr[i]/100, (float)total/100);
        }
        return (float)(total/ size)/100;
    }
    else
    {
        return 0.0;
    }
}

#elif (LIST == 120)

// 1-20 分数表达浮点数示例
long dtol( double d );
long gcd(long  a, long  b);

void convertdata(char *str);
struct
{
    long  zhengshu;
    long  xiaoshu;
    long  xunhuan;
    long  fenmu;
    long  fenzi;
}fenshu;

union udtol
{
    double d;
    long l;
};

long dtol( double d )
{
    union udtol to;
    to.d = d + 6755399441055744.0;
    return to.l;
}

long gcd(long  a, long  b)
{
    if(!b)
    {
        return a;
    }
    else
    {
        return gcd(b, a % b);
    }
}

void convertdata(char *str)
{
    int n = 0;
    int m = 0;
    int len=0;
    int len_1 = 0;
    int len_2 = 0;
    int len_3 = 0;
    char *p1;
    char *p2;
    char *p3;
    int i=0;
    int j=0;
    int z=0;
    long  gcb=0;
    fenshu.zhengshu =0;
    fenshu.xiaoshu =0;
    fenshu.xunhuan = 0;
    len = strlen(str);
    len_1 = len;
    p1 = strchr(str, '.');
    p2 = strchr(str, '(');
    p3 = strchr(str, ')');
    if(p1)
    {
        len_1 = p1 - str;
    }
    if(!p2)
    {
        len_2 = len - len_1 - 1;
    }
    if(p3)
    {
        len_2 = p2 - p1 - 1;
        len_3 = p3 - p2 - 1;
    }
    n = len_2;
    m = len_3;
    for(i = 0; i < len_1; i++)
    {
        fenshu.zhengshu *= 10;
        fenshu.zhengshu += str[i] - '0';
    }
    for(j = 0; j < len_2; j++)
    {
        fenshu.xiaoshu *= 10;
        fenshu.xiaoshu += str[len_1+1+j] - '0';
    }
    for(z = 0; z < len_3; z++)
    {
        fenshu.xunhuan *= 10;
        fenshu.xunhuan += str[len_1+len_2+2+z] - '0';
    }
    fenshu.fenmu =dtol((pow(10.0, (double)(m)) - 1.0) * (pow(10.0, (double)(n))));
    fenshu.fenzi = dtol(fenshu.xiaoshu * (pow(10.0, (double)(m)) - 1.0) + fenshu.xunhuan);
    gcb = gcd(fenshu.fenzi, fenshu.fenmu);
    fenshu.fenmu /= gcb;
    fenshu.fenzi /= gcb;
}

int main(void)
{
    for(;;)
    {
        char str[200] = "";
        printf("请输入要转换的数(如25.444(234)):");
        scanf("%s",&str);
        convertdata(str);
        printf("整数部分:%ld--小数部分:%ld--循环部分:%ld\n", fenshu.zhengshu,fenshu.xiaoshu,fenshu.xunhuan);
        printf("所得分数为:%ld/%ld\n", fenshu.fenzi,fenshu.fenmu);
        printf("-------------------------------------------\n");
    }
    return 0;
}

#elif (LIST == 121)
// 1=21 浮点数相等判断示例
int main(void)
{
    float f1=3.46f;
    float f2=5.77f;
    float f3=9.23f;
    printf("f1(3.46f)=%0.20f\nf2(5.77f)=%0.20f\nf1+f2=%0.20f\nf3(9.23f)=%0.20f\n",f1,f2,f1+f2,f3);
    if(f1+f2==f3)
    {
        printf("f1+f2==f3\n");
    }
    else
    {
        printf("f1+f2!=f3\n");
    }
    return 0;
}

// 将相对误差和绝对误差结合使用
bool IsEqual(float a, float b, float epsilon )
{
    if (a==b)
    {
        return true;
    }

    if (fabs(a-b)<epsilon ) // 绝对误差
    {
        return true;
    }

    if (fabs(a)>fabs(b)) // 相对误差
    {
        return (fabs((a-b)/a)< epsilon )?true:false;
    }
    else
    {
        return (fabs((a-b)/b)< epsilon )?true :false;
    } 
}

#elif (LIST == 122)
// 1-22 浮点数运算示例
int main(void)
{
    int i1=321;
    float f1=(float)(i1/9);
    float f2=i1/9.0f;
    float f3=(float)i1/9;
    float f4=(float)i1/9.0f;
    printf("(float)(i1/9)=%f\ni1/9.0f=%f\n(float)i1/9=%f\n(float)i1/9.0f=%f\n",f1,f2,f3,f4);
}

#endif